<?php namespace App\Utils\Weixin;

use GuzzleHttp\Client;
use App\Models\Channel;
use Illuminate\Support\Facades\Cache;

class WeixinUtils
{
    static public function newWeixinClient($clientKey = Channel::CHANNEL_WECHAT_1)
    {
        if (env("DEVELOPER") == "simon") {
            return self::newWxClient();
        }
        $keys = [Channel::CHANNEL_WECHAT_1, Channel::CHANNEL_WECHAT_2];
        if (!in_array($clientKey, $keys, TRUE)) $clientKey = Channel::CHANNEL_WECHAT_1;
        $wxConfigs = null;
        $wxConfigs = [
            "token" => config("weixin.$clientKey.token"),
            "encodingaeskey" => config("weixin.$clientKey.encodingaeskey"),
            "appid" => config("weixin.$clientKey.appid"),
            "appsecret" => config("weixin.$clientKey.appsecret"),
        ];
        $wxClient = new WechatRedisCache($wxConfigs);
        return $wxClient;
    }

    static public function newWxClient()
    {
        $wxConfigs = [
            "token" => env("wx.token"),
            "encodingaeskey" => env("wx.encodingaeskey"),
            "appid" => env("wx.appid"),
            "appsecret" => env("wx.appsecret"),
        ];
        $wxClient = new Wechat($wxConfigs);
        return $wxClient;
    }

    static public function getClientKey($openId) {
        $clientKeys = ['wx', 'wx2', 'wt'];
        foreach ($clientKeys as $clientKey) {
            if (strpos($openId, config("weixin.$clientKey.prefix")) === 0) {
                return $clientKey;
            }
        }
        return FALSE;
    }

    static public function getWeixinToken($appId, $appSecret, $code, $isWxx = false)
    {
        $cacheKey = "$appId:$code";
        $auth = Cache::get($cacheKey);
        if ($auth) {
            $authObject = json_decode($auth);
        } else {
            $client = new Client();
            if ($isWxx) {
                $wxResponse = $client->get("https://api.weixin.qq.com/sns/jscode2session?appid=$appId&secret=$appSecret&js_code=$code&grant_type=authorization_code");
            } else {
                $wxResponse = $client->post('https://api.weixin.qq.com/sns/oauth2/access_token', [
                    'form_params' => [
                        'appid' => $appId,
                        'secret' => $appSecret,
                        'code' => $code,
                        'grant_type' => 'authorization_code'
                    ]
                ]);
            }
            if ($wxResponse->getStatusCode() >= 400 || $wxResponse->getStatusCode() < 200) throw new InvalidWechatTokenRequestException();
            $authObject = json_decode($wxResponse->getBody());
            if (!isset($authObject->openid)) return false;
            Cache::put($cacheKey, json_encode($authObject), 118);
        }

        return $authObject;
    }

    static public function getWeixinOpenId($code)
    {
        $appId = config("weChat.appid");
        $appsecret = config("weChat.appsecret");
        $authObject = WeixinUtils::getWeixinToken($appId, $appsecret, $code);
        return $authObject ? $authObject->openid : false;
    }
}